package org.zxp.javacheck.keywords.transienttest;

import org.junit.Test;

import java.io.*;

/**
 * @program: effectiveJava
 * @description: transient测试
 * @author: X-Pacific zhang
 * @create: 2019-08-20 11:55
 **/
public class TransientTest {
    public static void main(String[] args) throws Exception {
        InnerSerializable obj = new InnerSerializable();
        obj.setFlag1(1);
        obj.setFlag2("2");
        obj.setFlag3(3.00D);
        obj.setFlag4("4");//这个变量是transient的
        System.out.println("序列化前："+obj);
        String path = "D://obj.bin";
        File f = new File(path);
        if (!f.exists()) {
            f.createNewFile();
        }
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
        out.writeObject(obj);
        out.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                new File(path)));
        obj = (InnerSerializable)ois.readObject();
        System.out.println("序列化后："+obj);
//        序列化前：InnerSerializable{flag1=1, flag2='2', flag3=3.0, flag4='4'}
//        序列化后：InnerSerializable{flag1=1, flag2='2', flag3=3.0, flag4='null'}
    }

    /**
     * Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时，JVM会把传来 的字节流中的serialVersionUID与本地相应实体（类）的serialVersionUID进行比较，如果相同就认为是一致的，可以进行反序 列化，否则就会出现序列化版本不一致的异常。
     * 当实现java.io.Serializable接口的实体（类）没有显式地定义一个名为serialVersionUID，类型为long的变 量时，Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用，这种情况下，只有同一次编译生成的 class才会生成相同的serialVersionUID 。
     * 如果我们不希望通过编译来强制划分软件版本，即实现序列化接口的实体能够兼容先前版本，未作更改的类，就需要显式地定义一个名为serialVersionUID，类型为long的变量，不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。
     */
    static class InnerSerializable implements Serializable {
        private static final long serialVersionUID = -3356893301182046019L;
        private int flag1;
        private String flag2;
        private double flag3;
        private transient String flag4;

        public int getFlag1() {
            return flag1;
        }

        public void setFlag1(int flag1) {
            this.flag1 = flag1;
        }

        public String getFlag2() {
            return flag2;
        }

        public void setFlag2(String flag2) {
            this.flag2 = flag2;
        }

        public double getFlag3() {
            return flag3;
        }

        public void setFlag3(double flag3) {
            this.flag3 = flag3;
        }

        public String getFlag4() {
            return flag4;
        }

        public void setFlag4(String flag4) {
            this.flag4 = flag4;
        }

        @Override
        public String toString() {
            return "InnerSerializable{" +
                    "flag1=" + flag1 +
                    ", flag2='" + flag2 + '\'' +
                    ", flag3=" + flag3 +
                    ", flag4='" + flag4 + '\'' +
                    '}';
        }
    }
}
